import { IConvertParser, IPlugIn, ITableData, ITableObj } from "../../inters/InterfaceApi";
import { Convert } from "../Convert";
import { codeMgr } from "../mgr/CodeMgr";
import { convertMgr } from "../mgr/ConvertMgr";
import { errLogMgr } from "../mgr/ErrLogMgr";
import { EnumTypeParser } from "../mgr/typeparser/EnumTypeParser";
import { JsonClsTypeParser, JsonTypeParser } from "../mgr/typeparser/JsonTypeParser";
import { typeParserMgr } from "../mgr/TypeParserMgr";
import { ICls, IJson } from "../utils/ClsFactory";
import { HashMap } from "../utils/HashMap";
import { IKeyVo, KeyVoUtil } from "../utils/KeyVoUtil";
import { TypeUtil } from "../utils/TypeUtil";
import { ValueUtil } from "../utils/ValueUtil";

export class JsonParser implements IPlugIn, IConvertParser {
    private _errLogs: string[];
    protected _hash: HashMap<any>;
    protected _clsList: Array<ICls>;
    private _data: ITableObj;
    convert: Convert;

    start(data: any, options?: any, callback?: (res?: any) => void) {
        this._data = data;
        return this;
    }

    public parseValue() {
        this.convert = convertMgr.crtConvert;
        let tableData: ITableObj = this._data;
        let keys = tableData.data[0];
        let descs = tableData.data[1];
        this._clsList = [];
        let keyVos: IKeyVo[] = []
        keys.forEach((keyStr, idx) => {
            let keyVo = KeyVoUtil.parserKey(keyStr, tableData.fileName);
            keyVo.des = descs[idx];

            keyVos.push(keyVo)
        })

        let values = this._data.data.slice(2);
        let realyKeys: IKeyVo[] = [];
        this._hash = new HashMap();
        for (let i = 0; i < values.length; i++) {
            var propList = values[i];
            if (propList.length == 0) continue;
            var key: string = "";
            var item: any = {};
            for (let j = 0; j < propList.length; j++) {
                let keyVo = keyVos[j];
                try {
                    var value = ValueUtil.parserValue(propList[j], keyVo);
                } catch (e) {
                    this._errLogs.push(this._data.fileName + ":" + propList[0] + "---" + keyVo.name + "--数据错误:" + e.message);
                }
                if (keyVo.primaryKey) {
                    key = value;
                }
                item[keyVo.name] = value;
            }
            if (key === "") {
                key = i.toString();
            }

            let type = item.type.toLocaleLowerCase();
            if (type == "jsoncls" || type == "jsonobj") {

                var keyVo: IKeyVo = { type, name: key, primaryKey: false, content: {} };
                let tp = convertMgr.crtConvert.convertCfg.tsOption.typePrefix;
                let jsonClsReplace = convertMgr.crtConvert.convertCfg.tsOption.jsonClsReplace;
                if (!jsonClsReplace) {
                    jsonClsReplace = "";
                }
                let typeName = tp + jsonClsReplace;
                let jsonVo: IJson = new IJson(typeName + key)
                let arr = item.content.split(",");
                for (let i = 0; i < arr.length; i++) {
                    var keyArr = arr[i].split(":");
                    let kn = keyArr[0];
                    let kt = keyArr[1];
                    let kdes = keyArr[2];
                    keyVo.content[kn] = kt;
                    jsonVo.addVar(kn, TypeUtil.getType(kt), !!kdes ? kdes : "");
                }
                keyVo.json = jsonVo;
                this._clsList.push(jsonVo);
                if (type == "jsonobj") {
                    typeParserMgr.registParser(key, new JsonTypeParser(key, keyVo));
                    typeParserMgr.registParser(key + "[]", new JsonTypeParser(key, keyVo));
                } else {
                    typeParserMgr.registParser(key, new JsonClsTypeParser(key, keyVo));
                    typeParserMgr.registParser(key + "[]", new JsonClsTypeParser(key, keyVo));
                }
                realyKeys.push(keyVo);
            }
            // if (vKeyVo != null) {
            //     typeParserMgr.registParser(key, new JsonTypeParser(key, vKeyVo));
            //     realyKeys.push(vKeyVo);
            // }
        }
        errLogMgr.addLog(this._errLogs)
        codeMgr.addCls(this._clsList);

        let tempTableData: ITableData = {
            type: "jsoncls",
            keys: realyKeys,
            tableName: tableData.fileName,
            data: null,
            errLog: this._errLogs,
            plat: tableData.platName
        }
        this.convert.addTableData(tempTableData, tableData.fileName, tableData.platName);
    }

    public getData() { return null; }

    get order() { return 90; }
}